<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>原型方法</title>
	</head>
	<body>
		
		<script >
			// 写法1
			var obj = {
				name:'孙悟空',
				age:18,
				sayName:fun
			}
			/**
			 * 尽量不往全局作用域定义函数或者变量，
			 * 容易污染作用域的命名空间
			 * 同时也很不安全
			 * */
			function fun(){
				alert(this.name);
			}

			function MyClass(){

			}

			var mc = new MyClass();

			var mc2 = new MyClass();

			/**
			 * 原型 prototype
			 * 
			 * 我们所创建的每一个函数，解析器都会向
			 * 函数添加一个属性prototype
			 * 也就是我们的原型对象
			 * 
			 * 如果函数作为普通函数prototype没有任何作用
			 * 当函数以构造函数形式调用时，他所创建的对象
			 * 都会有一个隐含的属性，指向构造函数的原型对象
			 * 我们可以通过__proto__来访问属性
			 * 
			 * 
			 * 原型对象都相当于一个公共的区域，所有同一个类的实例
			 * 都可以访问到这个原型对象，统一设置到原型对象中
			 * **/
			// true 这两个是同一个对象
			console.log(MyClass,'$',mc);
			console.log(MyClass.prototype == mc.__proto__);
			/**
			 * 当我们访问对象的一个属性或方法时，它会
			 * 现在对象自身中寻找，如果有就直接使用
			 * 如果没有则会去原型对象中寻找吗，如何找到
			 * 则直接使用。
			 * 
			 * **/
			// 使用in检查对象中是否含有某个属性时，如果对象中没有，但是原型里有，也会返回true
			 console.log("name" in mc);
			 // 如果使用对象的hasOwnProperty来检查对象自身中是否含有该属性
			 // 使用该方法只有当对象自身中含有属性时，不包括原型，才会返回true
			 console.log(mc.hasOwnProperty("age"));
			 // hasOwnProperty 方法我们也没定义过，但是却可以使用，是否也是原型里的呢
			 console.log(mc.hasOwnProperty("hasOwnProperty"));
			 // 还是false
			 console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));
			 /**
			  * 原型的对象也是对象，所以他也有原型,
			  * 当我们使用一个对象的属性或者方法时，会先在自身中寻找
			  * 1.自身中如果有，则直接使用
			  * 2.如果没有则去原型的原型中寻找，直找到Object对象的原型
			  * 3.Object对象的原型没有原型，如果在Object中已然没有找到，则返回undefined
			  * 
			  * **/
			  console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
				// 一般是两层
		</script>
	</body>
</body>
</html>
